package com.treeroot.stack;

/**
 * 定义一个 ArrayStack 表示栈
 */
public class ArrayStack {
    private int maxSize; // 栈的大小
    private int[] stack; // 数组，数组模拟栈，数据就放在该数组
    private int top = -1; // top 表示栈顶，初始化为 -1

    /**
     * 构造器
     */
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    /**
     * 栈满
     * q:为什么是maxSize-1
     * 因为top是从-1开始的，所以top+1=maxSize时，栈满
     */
    public boolean isFull() {
        return top == maxSize - 1;

    }

    /**
     * 栈空
     * q:为什么是-1
     * a:因为top是从-1开始的，所以top=-1时，栈空
     */
    public boolean isEmpty() {
        return top == -1;
    }

    /**
     * 入栈-push
     */
    public void push(int value) {
        // 先判断栈是否满
        if (isFull()) {
            System.out.println("栈满，无法加入数据~");
            return;
        }
        // top++; // 先移动指针，再赋值
        // stack[top] = value;
        stack[++top] = value;
    }

    /**
     * 出栈-pop，将栈顶的数据返回
     */
    public int pop() {
        // 先判断栈是否空
        if (isEmpty()) {
            // 抛出异常
            throw new RuntimeException("栈空，没有数据~");
        }
        int value = stack[top];
        top--;
        return value;
    }

    /**
     * 显示栈的情况[遍历栈]，遍历时，需要从栈顶开始显示数据
     */
    public void list() {
        if (isEmpty()) {
            System.out.println("栈空，没有数据~");
            return;
        }
        // 需要从栈顶开始显示数据
        for (int i = top; i >= 0; i--) {
            System.out.printf("stack[%d]=%d\n", i, stack[i]);
        }
    }
/**
 * -------------------- - --------------------给计算器类的提供方法-------------------  --------------------
 */
    /**
     * 返回运算符的优先级，优先级是程序员来确定，优先级使用数字表示,数字越大，则优先级越高
     * +*- /的本质是ASCII码
     */
    public int priority(int opera) {
        // 假定目前的表达式只有 +, - , * , /，
        if (opera == '*' || opera == '/') {
            return 1;
        } else if (opera == '+' || opera == '-') {
            return 0;
        } else {
            return -1;
        }
    }

    /**
     * 判断是不是一个运算符
     */
    public boolean isOpera(char val) {
        return val == '+' || val == '-' || val == '*' || val == '/';

    }

    /**
     * 计算方法
     */
    public int cal(int num1, int num2, int opera) {
        int res = 0; // res 用于存放计算的结果
        switch (opera) {
            case '+':
                res = num1 + num2;
                break;
            case '-':
                res = num2 - num1; // 注意顺序
                break;
            case '*':
                res = num1 * num2;
                break;
            case '/':
                res = num2 / num1; // 注意顺序
                break;
            default:
                break;
        }
        return res;
    }
    /**
     * peek方法，返回栈顶的值，但不是真正的pop
     */
    public int peek() {
        return stack[top];
    }
}